package cn.edu.zzuli.wechat.user.service.impl;

import cn.edu.zzuli.common.constant.RabbitConstant;
import cn.edu.zzuli.common.exception.CustomException;
import cn.edu.zzuli.model.dto.RunOrderDto;
import cn.edu.zzuli.model.entity.OfferOrder;
import cn.edu.zzuli.model.entity.RunOrder;
import cn.edu.zzuli.model.vo.order.AllOfferOrderQueryVo;
import cn.edu.zzuli.model.vo.all.DetailsQueryVo;
import cn.edu.zzuli.wechat.user.mapper.OfferOrderMapper;
import cn.edu.zzuli.wechat.user.mapper.RunOrderMapper;
import cn.edu.zzuli.wechat.user.service.RunOrderService;
import cn.edu.zzuli.common.utils.NowDate;
import cn.edu.zzuli.wechat.util.RedisUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class RunOrderServiceImpl extends ServiceImpl<RunOrderMapper, RunOrder> implements RunOrderService {

    @Autowired
    private OfferOrderMapper offerOrderMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedisUtils redisUtils;

    /**
     * 接单
     * @param id
     * @param session
     * @return
     */
    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    @Override
    public Integer addRunOrder(Integer id, HttpSession session) {
        Integer uid = (Integer) session.getAttribute("uid");

        //修改被接单用户的订单状态 + 乐观锁
        OfferOrder offerOrder = offerOrderMapper.selectById(id);
        Integer version = offerOrder.getVersion();
        OfferOrder offer = new OfferOrder();
        offer.setVersion(version + 1).setStatus(1);
        int res = offerOrderMapper.update(offer,new QueryWrapper<OfferOrder>().eq("version",version).eq("oid",offerOrder.getOid()));
        if(res == 0) {
            throw new CustomException("订单已被领取");
        }

        //对接取订单修改
        RunOrder runOrder = this.setOrder(id,uid);

        //增加接单到数据库
        int r = baseMapper.insert(runOrder);
        if(r == 0){
            throw new CustomException("接单失败!请再试一次");
        }

        //发送 message : id:订单号 type:类型 uid:当前操作用户
        String message = id + "|1|" + uid ;
        rabbitTemplate.convertAndSend(RabbitConstant.EXCHANGE,RabbitConstant.ROUTING_KEY_TAKE_ORDER
        ,message);

        return null;
    }

    /**
     * 接单列表
     * @param queryVo
     * @param uid
     * @return
     */
    @Override
    public Map<String, Object> queryRunOrderList(AllOfferOrderQueryVo queryVo, Integer uid) {
        //分页查询
        Page<RunOrderDto> pageCod = new Page<>(queryVo.getPage(),queryVo.getLimit());
        Page<RunOrderDto> offerOrderPage = baseMapper.queryList(pageCod,uid,queryVo.getType());
        //获得map集合
        Map<String,Object> map = this.getResultMap(offerOrderPage);
        return map;
    }

    /**
     * 查看订单的详情
     * @param detailsQueryVo
     * @return
     */
    @Override
    public Object getDetails(DetailsQueryVo detailsQueryVo) {
        int status = detailsQueryVo.getStatus();
        int id = detailsQueryVo.getId();
        Object res;
        if(status == 0  || status == 3 ){
            res = offerOrderMapper.selectById(id);
        }else if( status == 2  || status == 205 || status == 1 || status == 200 || status == 6){
            res = baseMapper.findById(id);
        }else{
            res = "奇怪的错误出现了";
        }
        return res;
    }


    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    @Override
    public void delRunOrder(int id, int i) {
        //删除接单表中该单数据
        int res = baseMapper.deleteById(id);
        if(res == 0){
            throw new CustomException("取消失败!");
        }
        //改变订单状态
        offerOrderMapper.updateById(new OfferOrder(id,0));
    }

    @Transactional(rollbackFor = {RuntimeException.class, Error.class})
    @Override
    public void applyFinish(Integer id,Integer uid) {
        String key = "order_";

        Date deadTime = NowDate.stringToDate(offerOrderMapper.getDeadTime(id));
        if(deadTime.getTime() < new Date().getTime()){
            baseMapper.updateById(new RunOrder(id,6));
        }else{
            baseMapper.updateById(new RunOrder(id,205));
        }
        int r1 = baseMapper.updateById(new RunOrder(NowDate.getNowTimes(),id));
        int r2 = offerOrderMapper.updateById(new OfferOrder(id,200));
        if(r1 == 0 || r2 == 0){
            throw new CustomException("出现错误");
        }

        //发送 message : id:订单号 type:类型 uid:当前操作用户
        String message = id + "|3|" + uid ;
        rabbitTemplate.convertAndSend(RabbitConstant.EXCHANGE,RabbitConstant.ROUTING_KEY_APPLY_ORDER
        ,message);

        //redis 监听
        redisUtils.set(key + id, id, 60);
    }


    //订单修剪
    private RunOrder setOrder(Integer id,Integer uid) {
        RunOrder runOrder = new RunOrder();
        runOrder.setRoid(id);
        runOrder.setRuid(uid);
        runOrder.setRunTime(NowDate.getNowTimes());
        return runOrder;
    }

    //获取map集合抽取的方法
    private Map<String, Object> getResultMap(Page offerOrderPage) {
        List<Object> records = null;
        long total = 0;
        if (offerOrderPage != null) {
            records = offerOrderPage.getRecords();
            total = offerOrderPage.getTotal();
        }
        Map<String, Object> map = new HashMap<>();
        map.put("code",200);
        map.put("msg","success");
        map.put("count",total);
        map.put("data",records);
        return map;
    }
}
